package pl.project.engineering.services;

import pl.project.engineering.logger.MailAppenderCreator;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import pl.project.engineering.data.MailServerConfig;
import pl.project.engineering.data.AlertEmailAddressList;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.List;
import java.util.Properties;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import pl.project.engineering.data.EmailInterval;
import pl.project.engineering.entities.AlertEmailAddress;
import pl.project.engineering.logger.RollingFileAppenderCreator;

/**
 *
 * @author ksmolnicki
 */
@Slf4j
@Data
public class AppConfig {

  private boolean isLoaded = false;

  private AlertEmailAddressList alertEmailAddressList;

  private MailServerConfig mailServerConfig;
  
  private String serialPortName;
  
  private String applicationJarDir;

  public AppConfig() {
    serialPortName = System.getProperty("port.name");
    this.applicationJarDir = System.getProperty("application.jar.dir");
    
    new RollingFileAppenderCreator().createRolingFileAppender(applicationJarDir);
    
    LoadConfigFile();
  }

  private void LoadConfigFile() {
    this.alertEmailAddressList = new AlertEmailAddressList();
    this.mailServerConfig = new MailServerConfig();
    File configFile = new File(applicationJarDir + File.separator + "application.properties");
    log.info("Loading config file from file: {}",configFile.getPath());
    if (!configFile.exists()) {
      return;
    }
    try {
      Properties prop = new Properties();
      prop.load(new FileInputStream(configFile)); 
      mailServerConfig.setUsername(prop.getProperty("mail.server.username"));
      mailServerConfig.setPassword(prop.getProperty("mail.server.password"));
      mailServerConfig.setSmtpHost(prop.getProperty("mail.server.smtp.host"));
      mailServerConfig.setPort(prop.getProperty("mail.server.port"));
      mailServerConfig.setEmailInterval(EmailInterval.valueOf(prop.getProperty("mail.server.interval.email")));
      mailServerConfig.setWarningTemp(Double.parseDouble(prop.getProperty("mail.server.warning.temperature")));
      mailServerConfig.setWarningHumd(Double.parseDouble(prop.getProperty("mail.server.warning.humidity")));

      for (String item : prop.getProperty("mail.server.alert.email.list").split(";")) {
        String[] alertEmail = item.split(",");
        AlertEmailAddress aea = new AlertEmailAddress();
        aea.setName(alertEmail[0]);
        aea.setEmail(alertEmail[1]);
        alertEmailAddressList.addAlertEmailAddress(aea);
      }
      isLoaded = true;
    } catch (Exception e) {
      log.error("Faild to load configuration file.", e);
    }
    new MailAppenderCreator().createMailAppender(this);
  }

  public boolean SaveConfigFile() {
    log.info("Saving configuration to file");
    if (!validate()) {
      return false;
    }
    File configFile = new File(applicationJarDir + File.separator + "application.properties");

    Properties prop = new Properties();
    prop.put("mail.server.username", mailServerConfig.getUsername());
    prop.put("mail.server.password", mailServerConfig.getPassword());
    prop.put("mail.server.smtp.host", mailServerConfig.getSmtpHost());
    prop.put("mail.server.port", mailServerConfig.getPort());
    prop.put("mail.server.interval.email", mailServerConfig.getEmailInterval().toString());
    prop.put("mail.server.warning.temperature", mailServerConfig.getWarningTemp().toString());
    prop.put("mail.server.warning.humidity", mailServerConfig.getWarningHumd().toString());
    
    List <String> alertEmails = Lists.transform(alertEmailAddressList.getAlertEmailAddresses(), new Function<AlertEmailAddress, String>() {
      @Override
      public String apply(AlertEmailAddress aea) {
        return aea.getName() + "," + aea.getEmail();
      }
    });
    prop.put("mail.server.alert.email.list", Joiner.on(";").skipNulls().join(alertEmails));

    try (FileOutputStream fos = new FileOutputStream(configFile)) {
      prop.store(fos, null);
    } catch (Exception e) {
      log.error("Error while saving configuration file.", e);
      return false;
    }
    isLoaded = true;
    new MailAppenderCreator().createMailAppender(this);
    return true;
  }

  private boolean validate() {

    if (Strings.isNullOrEmpty(mailServerConfig.getUsername())
            || Strings.isNullOrEmpty(mailServerConfig.getPassword())
            || Strings.isNullOrEmpty(mailServerConfig.getSmtpHost())
            || Strings.isNullOrEmpty(mailServerConfig.getPort())
            || this.alertEmailAddressList.getAlertEmailAddresses().isEmpty()) {
      return false;
    } else {
      return true;
    }
  }
}
